package com.excel;

import com.alibaba.excel.EasyExcel;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author xiang
 * @create 2021/7/1 14:35
 */
public class EasyExcelUtil {

    /**
     * 导出excel
     * @author xiang
     * @date 10:07 2021/9/9
     * @param  * @param outputStream
     * @param data
     * @return void
     **/
    public static void exportExcel(HttpServletResponse httpServletResponse, List data) throws IOException {
        prifixDeal(httpServletResponse,"excel导出");
        EasyExcel.write(httpServletResponse.getOutputStream(), data.get(0).getClass()).sheet("sheet").doWrite(data);
    }


    /**
     * 不使用任何模板，表头自定义
     * @author xiang
     * @date 10:33 2021/8/3
     * @param  * @param response
     * @param head 表头
     * @param name
     * @param dealFunction
     * @return void
     **/
    public static void createImportTemplate(HttpServletResponse response, String name, List head, SheetFunction dealFunction) throws IOException {
        prifixDeal(response,name);
        EasyExcel.write(response.getOutputStream()).sheet("sheet").registerWriteHandler(new ExcelHandler(dealFunction)).doWrite(head);
    }

    /**
     * 完全根据数据列表导出excel
     * @author xiang
     * @date 10:33 2021/8/3
     * @param  * @param response
     * @param data
     * @param name
     * @return void
     **/
    public static void createExport(HttpServletResponse response, String name, List data) throws IOException {
        prifixDeal(response,name);
        EasyExcel.write(response.getOutputStream()).sheet("sheet").doWrite(data);
    }

    /**
     * 根据实体类生成excel模板，dealFunction匿名函数是对excel的额外处理
     * @author xiang
     * @date 10:33 2021/8/3
     * @param  * @param response
     * @param templateClass
     * @param name
     * @param dealFunction
     * @return void
     **/
    public static void createImportTemplate(HttpServletResponse response, Class templateClass, String name, SheetFunction dealFunction) throws IOException {
        prifixDeal(response,name);
        EasyExcel.write(response.getOutputStream(), templateClass).sheet("sheet").registerWriteHandler(new ExcelHandler(dealFunction)).doWrite(new ArrayList());
    }

    /**
     * 根据实体类生成带下拉框的模板，box的键表示作用列，值表示下拉框的内容
     * @author xiang
     * @date 10:33 2021/8/3
     * @param  * @param response
     * @param templateClass
     * @param name
     * @param box 下拉框，键是列的index，值是下拉框内容list
     * @return void
     **/
    public static void createImportTemplate(HttpServletResponse response, Class templateClass, String name, Map<Integer,String[]> box) throws IOException {
        prifixDeal(response,name);
        EasyExcel.write(response.getOutputStream(), templateClass).sheet("sheet").registerWriteHandler(new ExcelHandler(boxF(box))).doWrite(new ArrayList());
    }
    private static SheetFunction boxF(Map<Integer,String[]> box){
        Set<Integer> indexes = box.keySet();
        return sheet->{
            for (Integer index : indexes) {
                String[] boxContent = box.get(index);
                //起始行、终止行、起始列、终止列
                CellRangeAddressList addressList = new CellRangeAddressList(1, 1000, index, index);
                /***设置下拉框数据**/
                DataValidationHelper helper = sheet.getDataValidationHelper();//设置下拉框
                DataValidationConstraint constraint = helper.createExplicitListConstraint(boxContent);
                DataValidation dataValidation = helper.createValidation(constraint, addressList);
                /***处理Excel兼容性问题**/
                if (dataValidation instanceof XSSFDataValidation) {
                    dataValidation.setSuppressDropDownArrow(true);
                    dataValidation.setShowErrorBox(true);
                } else {
                    dataValidation.setSuppressDropDownArrow(false);
                }
                sheet.addValidationData(dataValidation);
            }
        };
    }

    static void prifixDeal(HttpServletResponse response, String name) throws UnsupportedEncodingException {
        // 不用用swagger-ui测试访问
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 防止中文乱码
        String fileName = URLEncoder.encode(name, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    }

}
